//huffman.h

#ifndef HUFFMAN_H
#define HUFFMAN_H

//------------------
#include "variables.h"
#include "bitStream.h"
#include "compressor.h"
//------------------

//writeStruck |___9____|__9(!!)___|__7__|....|__data______|EOF
//               ^ symbols count                       
//                         ^symbol
//									 ^symbol's lvl
class HuffItem
{
	public:
		HuffItem* zero;
		HuffItem* one;

		int rate;        //symbols rate in file
		short value;    //symbol
		unchar code[257];     //haffman's code for f
		int bitsCount;  //used bits in haffman code

		HuffItem(short _value, int _rate);
};


class Huffman : public Compressor
{
	private:
		int tableCounter[256];
		unchar cTable[256];

		unchar CurrCode[257];
		int treeCounter;
		HuffItem** list; //list of elements
		int listCounter;
		HuffItem** tree; //tree

		long calcWeight();
		void writeHeader(BitStream& bs);
		int calcBitsInLastByte();
		void sortTable();
		int getSymbol(BitStream& bs, HuffItem* mark);
		void restoreTree(HuffItem* mark, int depth);
		void restoreTreeChecker(HuffItem* mark, int depth);
		void resortList(HuffItem* mark); //to save symbols in right oder
		void sortTree();
		void deleteTree(HuffItem* mark);
		int makeCodes(HuffItem* mark, unchar code, int bitsCount);
		void makeTree();
	public:
		Huffman();

		int getRate(FILE* file);
		
		int compress(FILE* fileIn, FILE* fileOut);
		int decompress(FILE* fileIn, FILE* fileOut);
		void clear();

		void showTable();
};

#endif
